package com.scs.application.core.utils;

import com.google.common.collect.Lists;
import net.sf.ehcache.Ehcache;
import net.sf.ehcache.Element;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.cache.ehcache.EhCacheCache;

import java.util.Collection;
import java.util.Collections;
import java.util.List;

/**
 * 本工具类只支持ehcache
 */
public class CacheUtils {

    private final static CacheManager cacheManager = SpringUtils.getBean(CacheManager.class);

    public static final String SYS_CACHE = "sysCache";
    public static final String AUTHENTICATION_CACHE = "authenticationCache";
    public static final String AUTHORIZATION_CACHE = "authorizationCache";
    public static final String DATAVIEW_CACHE = "dataview";


    /**
     * 获取所有缓存列表
     *
     * @return
     */
    public static List<Cache> getCacheList() {
        Collection<String> cacheNames = cacheManager.getCacheNames();
        List<Cache> cacheList = Lists.newArrayListWithCapacity(cacheNames.size());
        for (String cacheName : cacheNames) {
            cacheList.add(cacheManager.getCache(cacheName));
        }
        return cacheList;
    }

    public static List<String> getCacheKeys(String cacheName) {
        Cache cache = getCache(cacheName);
        if (cache == null) {
            return Collections.emptyList();
        }
        Object nativeCache = cache.getNativeCache();

        if (nativeCache instanceof net.sf.ehcache.Cache) {
            return ((net.sf.ehcache.Cache) nativeCache).getKeys();
        } else if (nativeCache instanceof org.springframework.cache.Cache) {
            if (nativeCache instanceof EhCacheCache) {
                return ((Ehcache) nativeCache).getKeys();
            }
        }


        return null;
    }

    public static Object getCacheValue(String cacheName, String key) {
        Cache cache = getCache(cacheName);
        if (cache == null) {
            return null;
        }
        Object nativeCache = cache.getNativeCache();
        if (nativeCache instanceof net.sf.ehcache.Cache) {
            Element element =  ((net.sf.ehcache.Cache) nativeCache).get(key);

            return element == null ? null : element.getObjectValue();
        }
        else if (nativeCache instanceof EhCacheCache) {
            Element element = ((Ehcache) nativeCache).get(key);
            return element == null ? null : element.getObjectValue();
        }
//        else if (nativeCache instanceof RedisCache) {
//            return null;
//        }
        return null;

    }

    /**
     * 获得一个Cache，没有则显示日志。
     *
     * @param cacheName
     * @return
     */
    private static Cache getCache(String cacheName) {
        Cache cache = cacheManager.getCache(cacheName);
        if (cache == null) {
            return null;
//            throw new RuntimeException("当前系统中没有定义“" + cacheName + "”这个缓存。");
        }
        return cache;
    }

    /**
     * 获取缓存
     *
     * @param cacheName
     * @param key
     * @return
     */
    public static Object get(String cacheName, String key) {
        Cache cache = getCache(cacheName);
        if (cache == null) {
            return null;
        }
        Cache.ValueWrapper valueWrapper = cache.get(key);

        return valueWrapper == null ? null : valueWrapper.get();
    }

    public static String getString(String cacheName,String key) {
        Object object = get(cacheName, key);
        return object == null ? null : object.toString();
    }

    /**
     * 获取SYS_CACHE缓存
     *
     * @param key
     * @return
     */
    public static Object get(String key) {
        return get(SYS_CACHE, key);
    }

    public static String getString(String key) {
        Object object = get(SYS_CACHE, key);
        return object == null ? null : object.toString();
    }

    public static Integer getInteger(String key) {
        Object object = get(SYS_CACHE, key);
        return object == null ? null :  Integer.valueOf(object.toString());
    }

    /**
     * 写入缓存
     *
     * @param cacheName
     * @param key
     * @param value
     */
    public static void put(String cacheName, String key, Object value) {
        Cache cache = getCache(cacheName);
        if (cache != null) {
            cache.put(key, value);
        }
    }
    /**
     * 写入SYS_CACHE缓存
     *
     * @param key
     * @return
     */
    public static void put(String key, Object value) {
        put(SYS_CACHE, key, value);
    }

    public static void remove(String cacheName, String key) {
        Cache cache = getCache(cacheName);
        if (cache != null) {
            cache.evict(key);
        }
    }

    public static boolean valueDel(String key) {
        remove(SYS_CACHE, key);
        return true;
    }



    public static boolean clearAll() {
        List<Cache> cacheList = getCacheList();
        for (Cache cache : cacheList) {
            cache.clear();
        }
        return true;
    }


    public static void clearCache(String cacheName) {
        Cache cache = getCache(cacheName);
        if (cache != null) {
            cache.clear();
        }
    }
}
